home *** CD-ROM | disk | FTP | other *** search
- """Common plugins for Louie."""
-
- from louie import dispatcher
- from louie import error
-
-
- def install_plugin(plugin):
- cls = plugin.__class__
- for p in dispatcher.plugins:
- if p.__class__ is cls:
- raise error.PluginTypeError(
- 'Plugin of type %r already installed.' % cls)
- dispatcher.plugins.append(plugin)
-
- def remove_plugin(plugin):
- dispatcher.plugins.remove(plugin)
-
-
- class Plugin(object):
- """Base class for Louie plugins.
-
- Plugins are used to extend or alter the behavior of Louie
- in a uniform way without having to modify the Louie code
- itself.
- """
-
- def is_live(self, receiver):
- """Return True if the receiver is still live.
-
- Only called for receivers who have already been determined to
- be live by default Louie semantics.
- """
- return True
-
- def wrap_receiver(self, receiver):
- """Return a callable that passes arguments to the receiver.
-
- Useful when you want to change the behavior of all receivers.
- """
- return receiver
-
-
- class QtWidgetPlugin(Plugin):
- """A Plugin for Louie that knows how to handle Qt widgets
- when using PyQt built with SIP 4 or higher.
-
- Weak references are not useful when dealing with QWidget
- instances, because even after a QWidget is closed and destroyed,
- only the C++ object is destroyed. The Python 'shell' object
- remains, but raises a RuntimeError when an attempt is made to call
- an underlying QWidget method.
-
- This plugin alleviates this behavior, and if a QWidget instance is
- found that is just an empty shell, it prevents Louie from
- dispatching to any methods on those objects.
- """
-
- def __init__(self):
- try:
- import qt
- except ImportError:
- self.is_live = self._is_live_no_qt
- else:
- self.qt = qt
-
- def is_live(self, receiver):
- """If receiver is a method on a QWidget, only return True if
- it hasn't been destroyed."""
- if (hasattr(receiver, 'im_self') and
- isinstance(receiver.im_self, self.qt.QWidget)
- ):
- try:
- receiver.im_self.x()
- except RuntimeError:
- return False
- return True
-
- def _is_live_no_qt(self, receiver):
- return True
-
-
- class TwistedDispatchPlugin(Plugin):
- """Plugin for Louie that wraps all receivers in callables
- that return Twisted Deferred objects.
-
- When the wrapped receiver is called, it adds a call to the actual
- receiver to the reactor event loop, and returns a Deferred that is
- called back with the result.
- """
-
- def __init__(self):
- # Don't import reactor ourselves, but make access to it
- # easier.
- from twisted import internet
- from twisted.internet.defer import Deferred
- self._internet = internet
- self._Deferred = Deferred
-
- def wrap_receiver(self, receiver):
- def wrapper(*args, **kw):
- d = self._Deferred()
- def called(dummy):
- return receiver(*args, **kw)
- d.addCallback(called)
- self._internet.reactor.callLater(0, d.callback, None)
- return d
- return wrapper
-
-